<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">

    <title>Vue3 Hello World 快速启动</title>
    <!--<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.0-beta.7/vue.global.js"></script>-->
    <script type="text/javascript" src="../js/vue.global.js"></script>

</head>
<body>
<!--vue 应用实例挂载到此ID上，这样它及其下面的标签才能使用 vue 语法获取数据-->
<!--双大括号和 v-text 指令都是取值进行填充, v-text 取值后会对标签的内容进行替换-->
<div id="rootApp" style="margin: 50px;font-size: 18px">
    <h3>Vue 插值 与 指令</h3>
    <hr/>
    <!--数据绑定最常见的形式就是使用双大括号的文本插值-->
    <!--类似 Thymeleaf 的内联表达式-->
    <!--双大括号将会被替代为对应组件实例中 msg 属性的值，只要对应组件实例上 msg 属性值发生了改变，插值处的内容都会更新-->
    <p>{{ msg }}</p>

    <p v-once>{{ msg }}</p>

    <!--v-text、v-html 指令分别类似 JQuery 的 text、html 函数-->
    <p v-text="author"></p>

    <!--双大括号、v-text 指令都会将 html 代码解释为普通文本(而非 HTML 代码),为了输出真正的 HTML,需要使用v-html 指令-->
    <div v-html="vHtml"></div>

    <!--v-bind指令为属性赋值,类似 Thymeleaf 的 th:attr 语法-->
    <!--这里的 src 是参数，告知 v-bind 指令将该元素的 src 属性与表达式 baiduLogoUrl 的值绑定-->
    <!--如果绑定的值是 null 或 undefined,那么该 attribute 将不会被包含在渲染的元素上-->
    <!--对于布尔值属性，只要存在就意味着值为 true, null 或 undefined、0 等同于 false-->
    <!--如果想对 v-bind 绑定的属性名称进行动态赋值,则可以使用[]括号动态参数取值-->
    <img v-bind:src="baiduLogoUrl" v-bind:[attr]="author" style="width: 200px;"/>
    <p><input type="checkbox" v-bind:checked="1">：是否本科毕业？</p>

    <!--指令中都可以进行 JavaScript 表达式运算-->
    <!--这些表达式会在当前活动实例的数据作用域下作为 JavaScript 被解析；但是每个绑定都只能包含单个表达式，而不能是 js 代码-->
    <div v-text="'性别：'+(sex==1?'男':'女')"></div>
    <!--将字符串内容反向-->
    <div v-text="msg.split('').reverse().join('')"></div>

    <h3>v-bind 缩写</h3>
    <hr/>
    <!--'v-' 前缀作为一种视觉提示，用来识别模板中 Vue 特定的 attribute，-->
    <!--然而对于一些频繁用到的指令来说，就会感到使用繁琐，v- 前缀也变得没那么重要了，-->
    <!--因此 Vue 为 v-bind 和 v-on 这两个最常用的指令，提供了特定简写：v-bind:xxx 可以省略 v-bind；v-on:xxx 可以省略 v-on，同时将 ':' 替换为 '@'-->
    <img :src="baiduLogoUrl" :[attr]="author" style="width: 200px;"/>

    <!--注意事项-->
    <!--1、对动态参数值约定：动态参数预期会求出一个字符串，异常情况下值为 null。这个特殊的 null 值可以被显性地用于移除绑定。任何其它非字符串类型的值都将会触发一个警告。-->
    <!--2、对动态参数表达式约定:动态参数表达式有一些语法约束，因为某些字符，如空格和引号，放在 HTML attribute 名里是无效的,-->
    <!--变通的办法是使用没有空格或引号的表达式，或用计算属性替代这种复杂表达式，-->
    <!--下面会触发编译警告-->
    <!--<a v-bind:['foo' + bar]="value"> ... </a>-->
    <!--3、在 DOM 中使用模板时(直接在一个 HTML 文件里撰写模板)需要避免使用大写字符来命名键名，因为浏览器会把属性名全部强制转为小写，-->
    <!--如下代码会被转换为 v-bind:[someattr]，除非实例中有一个名为'someattr'的属性，否则代码不会工作，-->
    <!--<a v-bind:[someAttr]="value"> ... </a>-->

</div>

</body>

<script type="text/javascript">
    //const baiduLogoUrl = 'https://www.baidu.com/img/flexible/logo/pc/result.png';
    const baiduLogoUrl = '../images/logo.png';
    const sex = 2;

    // 1、每个 Vue 应用都是通过用 createApp 函数创建一个新的应用实例开始, 用来在应用中注册"全局"组件
    // 2、传递给 createApp 的选项用于配置根组件
    // 3、应用实例暴露的大多数方法都会返回该同一实例，方便链式编程
    const App = Vue.createApp({
        //组件选项
        // data 定义数据, html 中可以进行获取
        data() {
            return {
                author: '蚩尤后裔',
                msg: 'Hello Vue!',
                vHtml: '<div style="color: red">v-html 指令解析 html 内容</div>',
                baiduLogoUrl,  //可以直接返回变量值
                attr: "title",
                sex
            }
        },
    });

    // 4、一个应用需要被挂载(mount)到一个 DOM 元素中，当挂载(mount)应用时，该组件被用作渲染的起点
    // 5、与大多数应用方法不同的是 mount 不返回应用本身，而是返回的根组件实例(vm)
    const rootViewModel = App.mount("#rootApp");

    // 在 data 中定义的 property(属性) 是通过组件实例暴露的
    // 还有各种其他的组件选项，可以将用户定义的 property 添加到组件实例中，例如 methods，props，computed，inject 和 setup
    // 组件实例的所有 property 无论如何定义，都可以在组件的模板中访问
    // Vue 还通过组件实例暴露了一些内置 property，如 $attrs 和 $emit(都有一个 $ 前缀,以避免与用户定义的 property 名冲突)
    console.log(rootViewModel.msg);

    // 6、大多数的真实应用都会被组织成一个嵌套的、可重用的组件树，比如一个 todo 应用组件树：
    // Root Component
    // └─ TodoList
    //    ├─ TodoItem
    //    │  ├─ DeleteTodoButton
    //    │  └─ EditTodoButton
    //    └─ TodoListFooter
    //       ├─ ClearTodosButton
    //       └─ TodoListStatistics
    // 7、每个组件将有自己的组件实例 vm，对于一些组件，如 TodoItem，在任何时候都可能有多个实例渲染。
    // 这个应用中的所有组件实例将共享同一个应用实例
    // 根组件与其他组件没什么不同，配置选项是一样的，所对应的组件实例行为也是一样的


</script>
</html>
